package top.ybq87;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 测试 synch 的几种不同的锁对象方式
 * @author ly
 * @email 664162337@qq.com
 * @date 2020/9/24 09:58
 */
public class SynchronizedTest implements Runnable {
    
    private static boolean flag = true;
    
    private static synchronized void testSyncMethod() { // 注意static修改的同步方法，监视器=class
        for (int i = 0; i < 100; i++) {
            System.out.println("testSyncMethod:" + i);
        }
    }
    
    // private void testSyncMethod() {
    //     synchronized (this) {
    //         for (int i = 0; i < 100; i++) {
    //             System.out.println("testSyncMethod:" + i);
    //         }
    //     }
    // }
    
    private void testSyncBlock() {
        
        synchronized (this) { // 注意this做为监视器．它与class分别是二个不同监视器．不会存在class被获取，this就要等的现象．这也是我以前关于监视器的一个误区．
            for (int i = 0; i < 100; i++) {
                System.out.println("testSyncBlock:" + i);
            }
        }
        
        // synchronized (RunnableTest.class) { // 显示使用获取class做为监视器．它与static synchronized method隐式获取class监视器一样．
        // for (int i = 0; i < 100; i++) {
        // System.out.println("testSyncBlock:" + i);
        // }
        // }
    }
    
    @Override
    public void run() {
        // flag是static的变量．所以，不同的线程会执行不同的方法,只有这样才能看到不同的锁定效果．
        if (flag) {
            flag = false;
            testSyncMethod();
        } else {
            flag = true;
            testSyncBlock();
        }
    }
    
    public static void main(String[] args) {
        ExecutorService exec = Executors.newFixedThreadPool(2);
        SynchronizedTest rt = new SynchronizedTest();
        SynchronizedTest rt1 = new SynchronizedTest();
        exec.execute(rt);
        exec.execute(rt1);
        exec.shutdown();
    }
}
